package org.one.stone.soup.grfxML.plugin.geometry;


import org.one.stone.soup.grfxML.DataPoint;
import org.one.stone.soup.grfxML.GrfxMLEngine;
import org.one.stone.soup.grfxML.GrfxMLProcessor;
import org.one.stone.soup.grfxML.plugin.SimplePlugin;
import org.one.stone.soup.grfxML.plugin.grfxMLCaster;
import org.one.stone.soup.mjdb.data.field.DataLinker;
import org.one.stone.soup.mjdb.data.field.Field;
import org.one.stone.soup.mjdb.data.field.LockException;

public class Spline extends SimplePlugin {


	public static final int ARG_POINTS = 0;

	public static final int ARG_ATTRACTORS = 1;

	public static final int ARG_STEPS = 2;

	public static final int ARG_TARGET = 3;



	org.one.stone.soup.grfxML.DataPoints points = new org.one.stone.soup.grfxML.DataPoints();

	org.one.stone.soup.grfxML.DataPoints attractors = new org.one.stone.soup.grfxML.DataPoints();

	org.one.stone.soup.grfxML.DataSize steps = new org.one.stone.soup.grfxML.DataSize();

	org.one.stone.soup.grfxML.DataPoints target = new org.one.stone.soup.grfxML.DataPoints();


/**
 * Spline constructor comment.
 */
public Spline(GrfxMLEngine engine) {
	super(engine);
}
/**
 *
 */
private void calculate()
{
 try{

	DataPoint t1;
	DataPoint t2;
	DataPoint at;

	int stepsValue = steps.getValue();

	target.setEmpty();

	for(int p=0;p<points.size();p++)
	{
		t1=points.get(p);
		at=attractors.get(p);

		if(p<points.size()-1)
		{
			t2=points.get(p+1);
		}
		else
		{
			t2=points.get(0);
		}

		/*at = at.getClone();
		grfxMLProcessor.sub(at,t1,at);
		at.setValueX( at.getValueX()*-1,this );
		at.setValueY( at.getValueY()*-1,this );
		grfxMLProcessor.add(at,t1,at);*/

		DataPoint v1 = new DataPoint();
		DataPoint v2 = new DataPoint();

/*		DataPoint ata = new DataPoint();
		grfxMLProcessor.sub(at,t1,ata);
		ata.setValueX( ata.getValueX()*2,this );
		ata.setValueY( ata.getValueY()*2,this );
		grfxMLProcessor.add(t1,ata,ata);

		grfxMLProcessor.sub(ata,t1,v1);
		grfxMLProcessor.sub(t2,ata,v2);*/

		GrfxMLProcessor.sub(at,t1,v1);
		GrfxMLProcessor.sub(t2,at,v2);

		float v1x = v1.getValueX();
		float v2x = v2.getValueX();

		float v1y = v1.getValueY();
		float v2y = v2.getValueY();

		float t1x = t1.getValueX();
		float t1y = t1.getValueY();

		float ptx = t1x;
		float pty = t1y;

		DataPoint pt = t1.getClone();
		target.add( pt,this );

		int aloop = stepsValue;
		int stepsSum = ((stepsValue+1)*stepsValue)/2;

		for(int loop=1;loop<stepsValue;loop++)
		{
			ptx=
					ptx+
					((v1x*aloop)/stepsSum)+
					((v2x*loop)/stepsSum);
			pty=
					pty+
					((v1y*aloop)/stepsSum)+
					((v2y*loop)/stepsSum);

			pt = new DataPoint();
			pt.setValueX((int)ptx,this);
			pt.setValueY((int)pty,this);
			target.add( pt,this );

			aloop--;
		}
	}

 }catch(LockException le){}
}
/**
 * initialize method comment.
 */
public void initialize()
{
	calculate();
}
/**
 * process method comment.
 */
public void process()
{
	calculate();
}
/**
 * register method comment.
 */
public void register(DataLinker store)
{

	points = grfxMLCaster.cast(points,getArg(points,ARG_POINTS,store));

	attractors = grfxMLCaster.cast(attractors,getArg(attractors,ARG_ATTRACTORS,store));

	steps = grfxMLCaster.cast(steps,getArg(steps,ARG_STEPS,store));

	target = grfxMLCaster.cast(target,getArg(target,ARG_TARGET,store));

}
/**
 * replace method comment.
 */
public void replace(Field oldObj, Field newObj)
{

	points = grfxMLCaster.replace(points,oldObj,newObj);

	attractors = grfxMLCaster.replace(attractors,oldObj,newObj);

	steps = grfxMLCaster.replace(steps,oldObj,newObj);

	target = grfxMLCaster.replace(target,oldObj,newObj);

}
/**
 * stop method comment.
 */
public void stop() {}
}
